package context

import (
	"context"
	"fmt"
	"time"
)

func ExampleRun(){
	//顶层routine
	ctx, cancel := context.WithCancel(context.Background())

	go func() {
		//调用gen函数，gen函数内部调用gen2函数，形成树结构
		for n := range gen(ctx) {
			fmt.Println(n)
			time.Sleep(1*time.Second)
		}
	}()

	//<-time.NewTicker(time.Second * 3).C	//3秒后取消context，会使整个上下文全部结束
	<-time.NewTicker(time.Second * 10).C	//10秒后取消context，此时gen2函数能够执行完毕
	cancel()
}

//第二层routine
func gen(ctx context.Context) <-chan int {
	dst := make(chan int)
	n := 1
	go func() {
		for {
			select {
			//如果上文传来done()，则结束该方法。
			case <-ctx.Done():
				return
			case dst <- n:
				n++
			}
		}
	}()
	//开启子routine，继续传递context
	go gen2(ctx)
	return dst
}

//第三层routine
func gen2(ctx context.Context) {
	//如果上文传来done()，则结束该方法。
	go func() {
		select {
		case <-ctx.Done():
			return
		}
	}()
	time.Sleep(time.Second * 5)
	fmt.Println("没有被中断，耗时5秒的任务执行完毕")
}
